package com.palm.dev.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.palm.dev.mode.GenOption;
import com.palm.dev.mode.Model;
import com.palm.dev.mode.Table;
import com.palm.dev.service.DMServices;
import com.palm.dev.service.ModelServices;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.Result;
import org.noear.solon.core.handle.UploadedFile;
import org.noear.solon.extend.sqltoy.annotation.Db;
import org.noear.solon.validation.annotation.NotBlank;
import org.sagacity.sqltoy.SqlToyContext;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.sagacity.sqltoy.utils.FileUtil;


import javax.sql.DataSource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Controller
@Mapping("dev")
public class DevController {

    @Inject
    DMServices dmServices;
    @Inject
    ModelServices modelServices;
    @Db
    DataSource dataSource;
    @Db
    SqlToyLazyDao dao;
    @Inject
    SqlToyContext sqlToyContext;
//    @Mapping(value = "upload",method = MethodType.POST)
//    public Result upload(@NotBlank String module, int upType, @NotBlank String prefix, Context ctx) throws Exception {
//        UploadedFile uf= ctx.file("file");
//        if(uf==null){
//            return Result.failure("没有上传文件");
//        }
//        String dir=modelServices.getModelDir();
//        if(module.indexOf(".")>-1||module.indexOf("/")>-1){
//            return Result.failure("模块名称不合法");
//        }
//        dir=dir+module;
//        File dirFile=new File(dir);
//        if(!dirFile.exists()){
//            dirFile.mkdirs();
//        }
//        String content=getContent(uf);
//        //Zving 模型文件
//        if(uf.name.endsWith(".zdm")){
//            Model model=dmServices.loadModel(content);
//            for(Table table:model.getTables()){
//                table.setModule(module);
//            }
//            saveTables(model.getTables(),upType);
//        }else if(uf.name.endsWith(".json")) {//Palm 模型
//
//        }else if(uf.name.endsWith(".ndm2")){//Navicat模型
//
//        }
//        return Result.succeed();
//    }
    @Mapping(value = "save",method = MethodType.PUT)
    public Result save(String id,@Param Table table) throws Exception {
        File file=new File(modelServices.getModelDir(),id);
        if(!id.endsWith(".json")){
            return Result.failure("文件名错误");
        }
       // StringUtil.write(file,JSON.toJSONString(table));
        String content=JSON.toJSONString(table,SerializerFeature.PrettyFormat);
        FileUtil.putStrToFile(content,file.getAbsolutePath(),"UTF-8");
        return Result.succeed();
    }
    @Mapping(value = "import",method = MethodType.POST)
    public Result importFromTable(@NotBlank String module,int upType,String prefix,String tables) throws Exception {
        String dir=modelServices.getModelDir();
        if(module.indexOf(".")>-1||module.indexOf("/")>-1){
            return Result.failure("模块名称不合法");
        }
        dir=dir+module;
        File dirFile=new File(dir);
        if(!dirFile.exists()){
            dirFile.mkdirs();
        }
        String []tbs=tables.split(",");
        List<Table> tableList=new ArrayList<>();
        for(String tb:tbs){
            Table table=modelServices.genTable(tb,prefix);
            if(table!=null){
                table.setModule(module);
                tableList.add(table);
            }
        }
        saveTables(tableList,upType);
       return Result.succeed();
    }

    private void saveTables(List<Table> tables,int upType) throws Exception {
        for(Table table:tables){
            String dir=modelServices.getModelDir();
            String module=table.getModule();
            if(module.indexOf(".")>-1||module.indexOf("/")>-1){
              continue;
            }
            dir=dir+module;
            File dirFile=new File(dir);
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }
            File dist=new File(dirFile,table.getCode()+".json");
            String content="";
            if(dist.exists()){
                switch (upType){
                    case 1://覆盖
                        //StringUtil.write(dist, JSON.toJSONString(table));
                        content=JSON.toJSONString(table,SerializerFeature.PrettyFormat);
                        FileUtil.putStrToFile(content,dist.getAbsolutePath(),"UTF-8");
                        break;
                    case 2://更新
                        updateTable(table,JSON.parseObject(FileUtil.readFileAsStr(dist,"UTF-8"),Table.class));
                        content=JSON.toJSONString(table,SerializerFeature.PrettyFormat);
                        FileUtil.putStrToFile(content,dist.getAbsolutePath(),"UTF-8");
                        break;
                    case 3://跳过
                        break;
                }
            }else {
                content=JSON.toJSONString(table,SerializerFeature.PrettyFormat);
                FileUtil.putStrToFile(content,dist.getAbsolutePath(),"UTF-8");
            }
        }
    }

    /**
     * 更新设计
     * @param newTable
     * @param old
     */
    private void updateTable(Table newTable,Table old){

    }
    @Mapping(value = "models",method = MethodType.POST)
    public Result models(){
        return modelServices.loadModels();
    }
    @Mapping(value = "del",method = MethodType.DELETE)
    public Result delete(String id){
        File f=new File(modelServices.getModelDir()+id);
        if(!f.exists()){
            return Result.failure("文件不存在");
        }
        if(f.isDirectory()){
            return Result.failure("文件错误");
        }
        f.delete();
        return Result.succeed();
    }
    @Mapping(value = "detail",method = MethodType.GET)
    public Result detail(String id) throws IOException {
        File f=new File(modelServices.getModelDir()+id);
        if(!f.exists()){
            return Result.failure("文件不存在");
        }
       String content=  FileUtil.readFileAsStr(f,"utf-8");
        return Result.succeed(JSON.parse(content));
    }
    @Mapping(value = "gen",method = MethodType.POST)
    public Result gen(String id, GenOption option){
        return modelServices.generate(id,option);
    }
    @Mapping(value = "tables",method = MethodType.POST)
    public Result tables(){
        return modelServices.loadTables();
    }
    private String getContent(UploadedFile uf) throws IOException {
        ByteArrayOutputStream bo=new ByteArrayOutputStream();
        uf.transferTo(bo);
        return bo.toString();
    }
    @Mapping(value = "sql",method = MethodType.POST)
    public Result sql(String sql){
       if(dataSource==null){
           return Result.succeed(new ArrayList<>());
       }
       List result= dao.findBySql(sql,new HashMap<>());
        return Result.succeed(result);
    }
    @Mapping("dicts")
    public Result dicts(){
      List result= dao.query()
              .sql("select sn `key`,name title from t_dictionary where type='dict'")
              .resultType(Map.class)
              .find();
      return Result.succeed(result);
    }
    @Mapping("translates")
    public Result translates(){
       Set<String> names =  sqlToyContext.getTranslateManager().getCacheNames();
       names.remove("dict");
       return Result.succeed(names);
    }
    @Mapping(value = "upload",method = MethodType.POST)
    public Result upload(@NotBlank String module,int upType,@NotBlank String prefix, Context ctx) throws Exception {
        UploadedFile uf= ctx.file("file");
        if(uf==null){
            return Result.failure("没有上传文件");
        }
        String dir=modelServices.getModelDir();
        if(module.indexOf(".")>-1||module.indexOf("/")>-1){
            return Result.failure("模块名称不合法");
        }
        dir=dir+module;
        File dirFile=new File(dir);
        if(!dirFile.exists()){
            dirFile.mkdirs();
        }
        String content=getContent(uf);
        //Zving 模型文件
        if(uf.name.endsWith(".zdm")){
            Model model=dmServices.loadModel(content);
            for(Table table:model.getTables()){
                table.setModule(module);
            }
            saveTables(model.getTables(),upType);
        }else if(uf.name.endsWith(".json")) {//Palm 模型

        }else if(uf.name.endsWith(".ndm2")){//Navicat模型

        }
        return Result.succeed();
    }
}
